#include "statement.h"
#include "recordset.h"

CStatementImpl::CStatementImpl(sqlite3* pSqlite3) :m_pSqlite3(pSqlite3)
{


}

CStatementImpl::~CStatementImpl(void)
{

}

std_method_impl CStatementImpl::Query(LPCSTR lpszSQL, UINT ulen, IRecordSet** pRecordSet)
{
	StmtPtr  pStmt3 = compile(m_pSqlite3, lpszSQL);
	rc_assert(pStmt3.m_p != NULL, E_FAIL)
	return CRecordSet::CreateInstance(pStmt3, pRecordSet);
}

std_method_type_impl(int) CStatementImpl::Execute(LPCSTR lpszSQL, UINT ulen)
{
	char *pszErrorMsg = NULL;

	StmtPtr  pStmt3 = compile(m_pSqlite3, lpszSQL);

	int rc = sqlite3_step(pStmt3);
	rc_assert(rc == SQLITE_DONE, S_ERROR)

	rc = sqlite3_changes(m_pSqlite3);

	return rc;
}

std_method_type_impl(int) CStatementImpl::Insert(LPCSTR lpszSQL, UINT ulen)
{
	char *pszErrorMsg = NULL;
	m_pStmt = compile(m_pSqlite3, lpszSQL);
	rc_assert(m_pStmt.m_p != NULL, E_FAIL)

	m_nParamCount = sqlite3_bind_parameter_count(m_pStmt);

	return m_nParamCount;
}

std_method_impl CStatementImpl::SetInt(unsigned int nIndex, INT nValue)
{
	rc_assert((nIndex > 0 || nIndex <= m_nParamCount), E_FAIL)
	int rc = sqlite3_bind_int(m_pStmt, nIndex, nValue);
	rc_assert(rc == SQLITE_OK, E_FAIL)
	return S_OK;
}

std_method_impl CStatementImpl::SetUInt(unsigned int nIndex, UINT nValue)
{
	rc_assert((nIndex > 0 || nIndex <= m_nParamCount), E_FAIL)
	int rc = SetInt64(nIndex, nValue);
	rc_assert(rc == SQLITE_OK, E_FAIL)
	return S_OK;
}

std_method_impl CStatementImpl::SetInt64(unsigned int nIndex, int64 nValue)
{
	rc_assert((nIndex > 0 || nIndex <= m_nParamCount), E_FAIL)
	int rc = sqlite3_bind_int64(m_pStmt, nIndex, nValue);
	rc_assert(rc == SQLITE_OK, E_FAIL)
	return S_OK;
}

std_method_impl CStatementImpl::SetDouble(unsigned int nIndex, double dbValue)
{
	rc_assert((nIndex > 0 || nIndex <= m_nParamCount), E_FAIL)
	int rc = sqlite3_bind_double(m_pStmt, nIndex, dbValue);
	rc_assert(rc == SQLITE_OK, E_FAIL)
	return S_OK;
}


std_method_impl CStatementImpl::SetFloat(unsigned int nIndex, float fValue)
{
	rc_assert((nIndex > 0 || nIndex <= m_nParamCount), E_FAIL)
	int rc = SetDouble(nIndex, fValue);
	rc_assert(rc == SQLITE_OK, E_FAIL)
	return S_OK;
}

std_method_impl CStatementImpl::SetBlob(unsigned int nIndex, const unsigned char* lpszData, int nSize)
{
	rc_assert(lpszData != NULL, E_INVALIDARG);
	rc_assert((nIndex > 0 || nIndex <= m_nParamCount), E_FAIL)
	int rc = sqlite3_bind_blob(m_pStmt, nIndex, lpszData, nSize, NULL);
	rc_assert(rc == SQLITE_OK, E_FAIL)
	return S_OK;
}


std_method_impl CStatementImpl::SetString(unsigned int nIndex, LPCSTR lpszData, int nSize)
{
	rc_assert((nIndex > 0 || nIndex <= m_nParamCount), E_FAIL)
	int rc = sqlite3_bind_text(m_pStmt, nIndex, lpszData, strlen(lpszData), NULL);
	rc_assert(rc == SQLITE_OK, E_FAIL)
	return S_OK;
}

std_method_impl CStatementImpl::SetDateTime(unsigned int nIndex, int64 nDateTime)
{
	rc_assert((nIndex > 0 || nIndex <= m_nParamCount), E_FAIL)
	int rc = SetInt64(nIndex, nDateTime);
	rc_assert(rc == SQLITE_OK, E_FAIL)
	return S_OK;
}

std_method_type_impl(int) CStatementImpl::Commit()
{
	int rc = sqlite3_step(m_pStmt);
	rc_assert(rc == SQLITE_DONE, E_FAIL)
	return sqlite3_changes(m_pSqlite3);
}

std_method_impl CStatementImpl::Free()
{
	m_pStmt.dispose();
	return S_OK;
}

std_method_impl CStatementImpl::Reset()
{
	int rc = sqlite3_reset(m_pStmt);
	rc_assert(rc == SQLITE_OK, E_FAIL)
	return S_OK;
}


